home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / retofinv.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  10KB  |  417 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10.  
  11. size_t retofinv_videoram_size;
  12. unsigned char *retofinv_sprite_ram1;
  13. unsigned char *retofinv_sprite_ram2;
  14. unsigned char *retofinv_sprite_ram3;
  15. unsigned char *retofinv_fg_char_bank;
  16. unsigned char *retofinv_bg_char_bank;
  17. unsigned char *retofinv_bg_videoram;
  18. unsigned char *retofinv_fg_videoram;
  19. unsigned char *retofinv_bg_colorram;
  20. unsigned char *retofinv_fg_colorram;
  21.  
  22. static unsigned char flipscreen=0;
  23. static unsigned char *bg_dirtybuffer;
  24. static unsigned bg_bank; /* last background bank active, 0 or 1 */
  25. static struct osd_bitmap *bitmap_bg;
  26.  
  27.  
  28. /* data corrections for color rom */
  29. static unsigned adj_data(unsigned v)
  30. {
  31.     /* reverse bits 4-7 */
  32.     return (v & 0xF) |
  33.             ((v & 0x80) >> 3) | ((v & 0x40) >> 1) | ((v & 0x20) << 1) | ((v & 0x10) << 3);
  34. }
  35.  
  36. void retofinv_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  37. {
  38.     int i;
  39.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  40.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  41.  
  42.  
  43.     for (i = 0;i < Machine->drv->total_colors;i++)
  44.     {
  45.         int bit0,bit1,bit2,bit3;
  46.  
  47.         bit0 = (color_prom[2*Machine->drv->total_colors] >> 0) & 0x01;
  48.         bit1 = (color_prom[2*Machine->drv->total_colors] >> 1) & 0x01;
  49.         bit2 = (color_prom[2*Machine->drv->total_colors] >> 2) & 0x01;
  50.         bit3 = (color_prom[2*Machine->drv->total_colors] >> 3) & 0x01;
  51.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  52.  
  53.         bit0 = (color_prom[1*Machine->drv->total_colors] >> 0) & 0x01;
  54.         bit1 = (color_prom[1*Machine->drv->total_colors] >> 1) & 0x01;
  55.         bit2 = (color_prom[1*Machine->drv->total_colors] >> 2) & 0x01;
  56.         bit3 = (color_prom[1*Machine->drv->total_colors] >> 3) & 0x01;
  57.  
  58.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  59.         bit0 = (color_prom[0*Machine->drv->total_colors] >> 0) & 0x01;
  60.         bit1 = (color_prom[0*Machine->drv->total_colors] >> 1) & 0x01;
  61.         bit2 = (color_prom[0*Machine->drv->total_colors] >> 2) & 0x01;
  62.         bit3 = (color_prom[0*Machine->drv->total_colors] >> 3) & 0x01;
  63.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  64.  
  65.         color_prom++;
  66.     }
  67.  
  68.     color_prom += 2*Machine->drv->total_colors;
  69.     /* color_prom now points to the beginning of the lookup table */
  70.  
  71.     /* foreground colors */
  72.     for (i = 0;i < TOTAL_COLORS(0);i++)
  73.     {
  74.         if (i % 2)
  75.             COLOR(0,i) = i/2;
  76.         else
  77.             COLOR(0,i) = 0;
  78.     }
  79.  
  80.     /* sprites */
  81.     for(i = 0;i < TOTAL_COLORS(2);i++)
  82.         COLOR(2,i) = adj_data(*color_prom++);
  83.  
  84.     /* background bank 0 (gameplay) */
  85.     /* background bank 1 (title screen) */
  86.     for(i = 0;i < TOTAL_COLORS(1);i++)
  87.         COLOR(1,i) = adj_data(color_prom[i]);
  88. }
  89.  
  90.  
  91. int retofinv_vh_start(void)
  92. {
  93.     if ((bg_dirtybuffer = malloc(retofinv_videoram_size)) == 0)
  94.     {
  95.         return 1;
  96.     }
  97.     if ((bitmap_bg = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  98.     {
  99.         free(bg_dirtybuffer);
  100.         return 1;
  101.     }
  102.     memset(bg_dirtybuffer,1,retofinv_videoram_size);
  103.     bg_bank = 0;
  104.     return 0;
  105. }
  106.  
  107. void retofinv_vh_stop(void)
  108. {
  109.     free(bg_dirtybuffer);
  110.     osd_free_bitmap(bitmap_bg);
  111. }
  112.  
  113. WRITE_HANDLER( retofinv_flip_screen_w )
  114. {
  115.     flipscreen = data;
  116.     memset(bg_dirtybuffer,1,retofinv_videoram_size);
  117.     fillbitmap(bitmap_bg,Machine->pens[0],0);
  118. }
  119.  
  120. READ_HANDLER( retofinv_bg_videoram_r )
  121. {
  122.     return retofinv_bg_videoram[offset];
  123. }
  124.  
  125. READ_HANDLER( retofinv_fg_videoram_r )
  126. {
  127.     return retofinv_fg_videoram[offset];
  128. }
  129.  
  130. READ_HANDLER( retofinv_bg_colorram_r )
  131. {
  132.     return retofinv_bg_colorram[offset];
  133. }
  134.  
  135. READ_HANDLER( retofinv_fg_colorram_r )
  136. {
  137.     return retofinv_fg_colorram[offset];
  138. }
  139.  
  140. WRITE_HANDLER( retofinv_bg_videoram_w )
  141. {
  142.     if (retofinv_bg_videoram[offset] != data)
  143.     {
  144.         bg_dirtybuffer[offset] = 1;
  145.         retofinv_bg_videoram[offset] = data;
  146.     }
  147. }
  148.  
  149. WRITE_HANDLER( retofinv_fg_videoram_w )
  150. {
  151.     if (retofinv_fg_videoram[offset] != data)
  152.         retofinv_fg_videoram[offset] = data;
  153. }
  154.  
  155. WRITE_HANDLER( retofinv_bg_colorram_w )
  156. {
  157.     if (retofinv_bg_colorram[offset] != data)
  158.     {
  159.         bg_dirtybuffer[offset] = 1;
  160.         retofinv_bg_colorram[offset] = data;
  161.     }
  162. }
  163.  
  164. WRITE_HANDLER( retofinv_fg_colorram_w )
  165. {
  166.     if (retofinv_fg_colorram[offset] != data)
  167.         retofinv_fg_colorram[offset] = data;
  168. }
  169.  
  170. void retofinv_render_sprites(struct osd_bitmap *bitmap)
  171. {
  172.     int offs,sx,sy,flipx,flipy,tile,palette,size;
  173.     int tileofs0,tileofs1,tileofs2,tileofs3;
  174.  
  175.     for (offs = 0; offs<127; offs+=2)
  176.     {
  177.         {
  178.             sx = 311-(((retofinv_sprite_ram2[offs+1] & 127) << 1) +
  179.                        ((retofinv_sprite_ram3[offs+1] & 128) >> 7) +
  180.                        ((retofinv_sprite_ram2[offs+1] & 128) << 1));
  181.  
  182.             sy =       ((retofinv_sprite_ram2[offs] & 127) << 1) +
  183.                        ((retofinv_sprite_ram3[offs] & 128) >> 7) +
  184.                        ((retofinv_sprite_ram2[offs] & 128) << 1);
  185.  
  186.             tile    = retofinv_sprite_ram1[offs];
  187.             size    = retofinv_sprite_ram3[offs];
  188.             palette = retofinv_sprite_ram1[offs+1] & 0x3f;
  189.  
  190.             flipx = 0;
  191.             flipy = 0;
  192.             tileofs0 = 0;
  193.             tileofs1 = 1;
  194.             tileofs2 = 2;
  195.             tileofs3 = 3;
  196.  
  197.             if (flipscreen)
  198.             {
  199.                 tileofs0 = 2;
  200.                 tileofs2 = 0;
  201.                 tileofs1 = 3;
  202.                 tileofs3 = 1;
  203.                 flipx = flipy = 1;
  204.             }
  205.  
  206.             if (!(size & 12))
  207.             {
  208.                 /* Patch for disappearing invadres' missile,
  209.                          could it be Z80 bug ? */
  210.                 if (tile==0x98) tile--;
  211.  
  212.                 drawgfx(bitmap,Machine->gfx[2],
  213.                             tile,
  214.                             palette,
  215.                             flipx,flipy,
  216.                             sx,sy,
  217.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  218.             }
  219.             if (size & 4)
  220.             {
  221.                 if ((size & 8) && (flipscreen)) sx-=16;
  222.                 drawgfx(bitmap,Machine->gfx[2],
  223.                             tile+tileofs0,
  224.                             palette,
  225.                             flipx,flipy,
  226.                             sx,sy+16,
  227.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  228.  
  229.                 drawgfx(bitmap,Machine->gfx[2],
  230.                             tile+tileofs2,
  231.                             palette,
  232.                             flipx,flipy,
  233.                             sx,sy,
  234.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  235.             }
  236.             if (size & 8)
  237.             {
  238.                 if (flipscreen) sx+=32;
  239.                 drawgfx(bitmap,Machine->gfx[2],
  240.                             tile+tileofs1,
  241.                             palette,
  242.                             flipx,flipy,
  243.                             sx-16,sy+16,
  244.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  245.  
  246.                 drawgfx(bitmap,Machine->gfx[2],
  247.                             tile+tileofs3,
  248.                             palette,
  249.                             flipx,flipy,
  250.                             sx-16,sy,
  251.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  252.             }
  253.         }
  254.     }
  255. }
  256.  
  257.  
  258. void retofinv_draw_background(struct osd_bitmap *bitmap)
  259. {
  260.     int x,y,offs;
  261.     int sx,sy,tile,palette;
  262.     int bg_dirtybank;
  263.  
  264.     /* for every character in the Video RAM, check if it has been modified */
  265.     /* since last time and update it accordingly. */
  266.  
  267.     /* if bank differ redraw all */
  268.     bg_dirtybank = (retofinv_bg_char_bank[0] & 1) != bg_bank;
  269.  
  270.     /* save active bank */
  271.     bg_bank = (retofinv_bg_char_bank[0] & 1);
  272.  
  273.     for (y = 31; y>=0; y--)
  274.     {
  275.         for (x = 31; x>=0; x--)
  276.         {
  277.             offs = y*32+x;
  278.  
  279.             if (bg_dirtybank || bg_dirtybuffer[offs])
  280.             {
  281.                 sx = 31-x;
  282.                 sy = 31-y;
  283.  
  284.                 if (flipscreen)
  285.                 {
  286.                     sx = 31 - sx;
  287.                     sy = 31 - sy;
  288.                 }
  289.  
  290.                 bg_dirtybuffer[offs] = 0;
  291.                 tile = retofinv_bg_videoram[offs] + 256 * bg_bank;
  292.                 palette = retofinv_bg_colorram[offs] & 0x3f;
  293.  
  294.                 drawgfx(bitmap_bg,Machine->gfx[1],
  295.                         tile,
  296.                         palette,
  297.                         flipscreen,flipscreen,
  298.                         8*sx+16,8*sy,
  299.                         &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  300.             }
  301.         }
  302.     }
  303.  
  304.     copybitmap(bitmap,bitmap_bg,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  305. }
  306.  
  307.  
  308. void retofinv_draw_foreground(struct osd_bitmap *bitmap)
  309. {
  310.     int x,y,offs;
  311.     int sx,sy,tile,palette,flipx,flipy;
  312.  
  313.     for (x=0; x<32; x++)
  314.     {
  315.         for (y = 30; y<=31; y++)
  316.         {
  317.             offs = y*32+x;
  318.  
  319.             sx = ((62-y)+3) << 3;
  320.             sy = (31-x) << 3;
  321.  
  322.             flipx = flipy = 0;
  323.  
  324.             if (flipscreen)
  325.             {
  326.                 sx = 280 - sx;
  327.                 sy = 248 - sy;
  328.                 flipx = flipy = 1;
  329.             }
  330.  
  331.             tile = retofinv_fg_videoram[offs]+(retofinv_fg_char_bank[0]*256);
  332.             palette = retofinv_fg_colorram[offs];
  333.  
  334.             drawgfx(bitmap,Machine->gfx[0],
  335.                           tile,
  336.                           palette,
  337.                           flipx,flipy,
  338.                           sx,sy,
  339.                           &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  340.         }
  341.     }
  342.  
  343.     for (x = 29; x>=2 ;x--)
  344.     {
  345.         for (y = 31; y>=0; y--)
  346.         {
  347.             offs = x*32+y;
  348.             sy = ((31-x) << 3);
  349.             sx = ((33-y)) << 3;
  350.  
  351.             flipx = flipy = 0;
  352.  
  353.             if (flipscreen)
  354.             {
  355.                 sx = 280 - sx;
  356.                 sy = 248 - sy;
  357.                 flipx = flipy = 1;
  358.             }
  359.  
  360.             tile = retofinv_fg_videoram[offs]+(retofinv_fg_char_bank[0]*256);
  361.             palette = retofinv_fg_colorram[offs];
  362.  
  363.             drawgfx(bitmap,Machine->gfx[0],
  364.                           tile,
  365.                           palette,
  366.                           flipx,flipy,
  367.                           sx,sy,
  368.                           &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  369.         }
  370.     }
  371.  
  372.     for (x=0; x<32; x++)
  373.     {
  374.         for (y = 1; y>=0; y--)
  375.         {
  376.             offs = y*32+x;
  377.             sx = (1-y) << 3;
  378.             sy = (31-x) << 3;
  379.  
  380.             flipx = flipy = 0;
  381.  
  382.             if (flipscreen)
  383.             {
  384.                 sx = 280 - sx;
  385.                 sy = 248 - sy;
  386.                 flipx = flipy = 1;
  387.             }
  388.  
  389.             tile = retofinv_fg_videoram[offs]+(retofinv_fg_char_bank[0]*256);
  390.             palette = retofinv_fg_colorram[offs];
  391.  
  392.             drawgfx(bitmap,Machine->gfx[0],
  393.                           tile,
  394.                           palette,
  395.                           flipx,flipy,
  396.                           sx,sy,
  397.                           &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  398.         }
  399.     }
  400. }
  401.  
  402.  
  403. /***************************************************************************
  404.  
  405.   Draw the game screen in the given osd_bitmap.
  406.   Do NOT call osd_update_display() from this function, it will be called by
  407.   the main emulation engine.
  408.  
  409. ***************************************************************************/
  410.  
  411. void retofinv_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  412. {
  413.     retofinv_draw_background(bitmap);
  414.     retofinv_render_sprites(bitmap);
  415.     retofinv_draw_foreground(bitmap);
  416. }
  417.